<template>
    <div id='wrap'>
        <div v-if="isShow">
            <div>countA:{{ abc.countA }}</div>
            <div>countB:{{ abc.countB }}</div>
            <button @click="abc.incrementA">incrementA</button>
            <button @click="abc.incrementB">incrementB</button>
            <button @click="stopScope">销毁作用域</button>
        </div>
        <hr>
        <div v-show="isStop">
            <h3>计数器的作用域已经销毁</h3>
        </div>
    </div>
</template>
<script lang='ts'>
export default {
    name: 'vue',
}
</script>
<script lang='ts' setup>
import { ref, h, type Ref, isRef, reactive, isReactive, readonly, isReadonly, toRef, toRefs, unref, isProxy, effectScope, onScopeDispose, EffectScope } from 'vue';
interface classA {
    countA: Ref<number>,
    countB: Ref<number>,
    incrementA: () => void,
    incrementB: () => void
}
let scope: EffectScope; //用于存储effectScope实例
const isShow: Ref<boolean> = ref(false);


//创建effectScope实例
function setupScope(): Promise<classA> {
    //创建一个新的作用域
    scope = effectScope();
    let time: ReturnType<typeof setInterval>;
    let timer: ReturnType<typeof setInterval>
    //返回一个promise对象
    return new Promise((resolve) => {
        //在该作用域运行所有的响应式
        scope.run(() => {
            const countA = ref(0);
            const countB = ref(0);
            const incrementA = () => {
                time = setInterval(() => {
                    countA.value++;
                }, 500)
            }
            const incrementB = () => {
                timer = setInterval(() => {
                    countB.value++;
                }, 500)
            }
            //清理回调
            onScopeDispose(() => {
                clearInterval(time);
                clearInterval(timer);
                console.log('作用域已停止，清理资源')
            })
            //返回需要在模板中使用的状态
            resolve({ countA, countB, incrementA, incrementB })
        })
    });
}

let abc: classA;
const initScope = async () => {
    //调用setupScope，初始化作用域中的状态
    abc = await setupScope();
    console.log(abc.countA);
    isShow.value = true;
}
//停止作用域的函数
const isStop = ref(false);
function stopScope() {
    if (scope) {
        scope.stop();//停止作用域并触发销毁回调
        isStop.value = true;
    }
}
initScope()
</script>
<style lang='scss'>
@use '@/assets/common.scss';
</style>